/**
  * @addtogroup nvm_queue
  * nvm_queue
  *
  * @brief
  *
  * @code  使用说明示例
  * @endcode
  * @{
  * @file         nvm_queue.h 
  * @brief
  * @note
  * @author       zhengganle
  * @date         2022-10-21
  * @version      1.0
  * 
  * @par          修改日志
  * <table>
  * <tr><th>Date        <th>Version          <th>Author                        <th>Description
  * <tr><td>2022-10-21  <td>1.0              <td>ganle.zheng@hopechart.com     <td>创建初始版本
  * @copyright    杭州鸿泉物联网技术股份有限公司
  */
#ifndef _NVM_QUEUE_H_
#define _NVM_QUEUE_H_

#include "ofc/ofc_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 打开模式
 */
enum TNvmQueueOpenModeTag
{
    kNvmQueueOpenNormal         =  0,       ///< 正常打开
    kNvmQueueOpenCanFormat      =  1,       ///< 正常打开, 若失败则格式化
    kNvmQueueOpenNeedFormat     =  2,       ///< 格式化后打开
};      
typedef enum TNvmQueueOpenModeTag TNvmQueueOpenMode;

/**
 * 队列错误码
 */
enum TNvmQueueResultTag
{
    TNvmQueueRstOk        =  0,  ///< 成功
    TNvmQueueRstError     = -1, ///< 失败
    TNvmQueueRstVersion   = -2, ///< 版本不匹配
    TNvmQueueRstParam     = -3, ///< 参数不合法
    TNvmQueueRstNotExist  = -4, ///< 队列不存在
    TNvmQueueRstSize      = -5, ///< 尺寸不合法(如:读缓存尺寸不够)
};
/**
 * 版本号
 * @param 
 * @return 版本号 如: 0x0708090A 表示 7.8.9.10,当前版本号:1.0.0.1
 */
Int32 NvmQueueVesion(void);

/**
 * 打开队列
 * @param queue_id: 队列索引ID
 * @param mode: 打开模式
 * @return 0:成功 其他:失败 参考 THccMidNvmErrorCodeEnumTag
 */
Int32 NvmQueueOpen(UInt16 queue_id, TNvmQueueOpenMode mode);

/**
 * 判断队列是否打开
 * @param queue_id: 队列索引ID
 * @return True:成功 False:失败
 */
Bool NvmQueueIsOpened(UInt16 queue_id);

/**
 * 关闭队列
 * @param queue_id: 队列索引ID
 * @return 
 */
void NvmQueueClose(UInt16 queue_id);

/**
 * 数据队列存入数据项
 * @param queue_id: 队列索引ID
 * @param data: 数据
 * @param size: 数据长度
 * @return 消息发送结果 等于0:成功
 *                      负数:失败 参考 THccMidNvmErrorCodeEnumTag
 */
Int32 NvmQueuePush(UInt16 queue_id, const void *data, UInt32 size);

/**
 * 数据队列存入数据项扩展
 * @param queue_id: 队列索引ID
 * @param head: 头部数据
 * @param head_size: 头部数据长度
 * @param body: 数据体
 * @param body_size: 数据体长度
 * @return 消息发送结果 等于0:成功 
 *                      负数:失败 参考 THccMidNvmErrorCodeEnumTag
 */
Int32 NvmQueuePushEx(UInt16 queue_id, const void *head, UInt32 head_size, const void *body, UInt32 body_size);

/**
 * 预读数据项
 * @param queue_id: 队列索引ID
 * @param buffer: 数据缓存
 * @param buf_size: 数据缓存长度
 * @return 消息发送结果 大于等于0: 实际数据项长度 
 *                     负数:失败 参考 THccMidNvmErrorCodeEnumTag
 */
Int32 NvmQueuePeek(UInt16 queue_id, void *buffer, UInt32 buf_size);

/**
 * 读取数据项
 * @param queue_id: 队列索引ID
 * @param buffer: 数据缓存
 * @param buf_size: 数据缓存长度
 * @return 消息发送结果 大于等于0: 实际数据项长度 
 *                     负数:失败 参考 THccMidNvmErrorCodeEnumTag
 */
Int32 NvmQueuePop(UInt16 queue_id, void *buffer, UInt32 buf_size);

/**
 * 队列含有总项数，包含已经Pop过的数据项目
 * @param queue_id: 队列索引ID
 * @return -1:失败 大于等于0: 实际数据项数
 */
Int32 NvmQueueTotalCount(UInt16 queue_id);

/**
 * 队列含有未Pop的项数
 * @param queue_id: 队列索引ID
 * @return -1:失败 大于等于0: 实际数据项数
 */
Int32 NvmQueuePopCount(UInt16 queue_id);

/**
 * 删除所有未Pop数据项
 * @param queue_id: 队列索引ID
 * @return
 */
void NvmQueueClear(UInt16 queue_id);

/**
 * 删除未Pop数据项
 * @param queue_id: 队列索引ID
 * @param count: 删除数据项数量
 * @return 
 */
void NvmQueueDelete(UInt16 queue_id, UInt32 count);

/**
 * 强制刷新队列缓冲区
 * @param queue_id: 队列索引ID
 * @return 
 */
void NvmQueueFlush(UInt16 queue_id);

/// 随机读取

/**
 * 迭代器定位到存储首项[用作从前向后读取]
 * @param queue_id: 队列索引ID
 * @return 小于:失败 参见TDsQueueResult 大于等于0: 查询迭代器操作句柄 query_id
 */
Int32 NvmQueueQueryStoreFirstIterOpen(UInt16 queue_id);

/**
 * 迭代器定位到待Pop首项[用作从前向后读取]
 * @param queue_id: 队列索引ID
 * @return 小于:失败 参见TDsQueueResult 大于等于0: 查询迭代器操作句柄 query_id
 */
Int32 NvmQueueQueryPopFirstIterOpen(UInt16 queue_id);

/**
 * 迭代器定位到Start首项[用作读取开机往后的数据]
 * @param queue_id: 队列索引ID
 * @return 小于:失败 参见TDsQueueResult 大于等于0: 查询迭代器操作句柄 query_id
 */
Int32 NvmQueueQueryStoreStartIterOpen(UInt16 queue_id);

/**
 * 迭代器定位到最后一次Push项[用作从后向前读取]?
 * @Todo 是否需要
 * @param queue_id: 队列索引ID
 * @return 小于:失败 参见TDsQueueResult 大于等于0: 查询迭代器操作句柄 query_id
 */
Int32 NvmQueueQueryLastPushIterOpen(UInt16 queue_id);

/**
 * 依次迭代读取数据项[从前向后读取]
 * @param query_id: 迭代器操作句柄
 * @param buffer: 接收缓存. 若为 NULL 则忽略 buf_size 参数并返回项所需尺寸
 * @param buf_size: 缓存长度
 * @return -1:失败 大于0: 实际数据项数 获取成功后会定位到下一项
 */
Int32 NvmQueueQueryIterItem(Int32 query_id, void* buffer, UInt32 buf_size);

/**
 * 关闭查询队列
 * @param query_id: 迭代器操作句柄
 * @return 
 */
void NvmQueueQueryClose(Int32 query_id);


/**
 * 迭代器定位到下一项[从前向后移动]
 * @note 配合 NvmQueueQueryStoreFirstIterOpen() 和 NvmQueueQueryIterItem() 计算已存储的数据大小
 * @param query_id 迭代器操作句柄
 * @return 成功 > 0
 *         失败 <= 0
 */
Int32 NvmQueueQueryNextItem(Int32 query_id);

#ifdef __cplusplus
} // extern "C" {
#endif

#endif	// _NVM_QUEUE_H_

/**
 * @}
 */



